package cn.matezk.lianlian.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.matezk.lianlian.beans.ForbiddenException;
import cn.matezk.lianlian.beans.NoauthException;
import cn.matezk.lianlian.model.DeviceBind;
import cn.matezk.lianlian.model.SecretKey;
import cn.matezk.lianlian.service.IDeviceBindService;
import cn.matezk.lianlian.service.ISecretKeyService;
import cn.matezk.lianlian.utils.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;

@Slf4j
public class BaseController {
    @Autowired
    private ISecretKeyService secretKeyService;
    @Autowired
    private IDeviceBindService deviceBindService;

    private String getClientIP(HttpServletRequest request) {
        String xForwardedForHeader = request.getHeader("X-Forwarded-For");
        if (xForwardedForHeader == null) {
            return request.getRemoteAddr();
        } else {
            // 可能有多个IP地址，第一个通常是客户端的公网地址
            return xForwardedForHeader.split(",")[0].trim();
        }
    }

    void auth(HttpServletRequest request, JSONObject params) throws NoauthException, ForbiddenException {
        String authorization = request.getHeader("Authorization");
        if (ObjectUtil.equals(authorization, "CNT8Q1AkIpqQzXfx5EUOwRWYOzEOOXeu"))   return;
        String appKey = request.getHeader("appKey");
        if (ObjectUtil.isEmpty(appKey))
            throw new NoauthException("header appKey is null");
        String token = request.getHeader("token");
        if (ObjectUtil.isEmpty(token))
            throw new NoauthException("header token is null");
        String tsStr = request.getHeader("ts");
        if (ObjectUtil.isEmpty(tsStr))
            throw new NoauthException("header ts is null");
        Long ts = Long.valueOf(tsStr);
        if (Math.abs((int)(Calendar.getInstance().getTimeInMillis() - ts)) >= 1000 * 300) {
            throw new NoauthException("时间戳已过期");
        }
        SecretKey secretKey = secretKeyService.selectByAppKey(appKey);
        if (ObjectUtil.isNull(secretKey))
            throw new NoauthException("无效的Token");
        if (Boolean.FALSE.equals(secretKey.getEnable()))
            throw new NoauthException("账号已禁用");
        String localToken = TokenUtil.createToken(appKey, secretKey.getSecret(), Long.valueOf(ts), params);
        if (!localToken.equals(token))
            throw new NoauthException("无效的Token");
        if (params.containsKey("productId") && params.containsKey("deviceName")) {
            // 查询是否有控制设备的权限
            DeviceBind device = deviceBindService.selectByAppKeyProductDevice(appKey, params.getStr("productId"), params.getStr("deviceName"));
            if (ObjectUtil.isNull(device))
                throw new ForbiddenException("无该设备的操作权限");
        }
        log.info("appKey {} 访问系统 {} IP {}", appKey, request.getRequestURI(), getClientIP(request));
    }
}
